home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcl / src-16f.lha / ldb / breakpoint.c < prev    next >
C/C++ Source or Header  |  1991-12-22  |  3KB  |  147 lines

  1. #include <stdio.h>
  2. #include <signal.h>
  3.  
  4. #include "ldb.h"
  5. #include "lisp.h"
  6. #include "os.h"
  7. #include "lispregs.h"
  8. #include "globals.h"
  9.  
  10. #ifdef ibmrt
  11. typedef unsigned short inst;
  12. #else
  13. typedef unsigned long inst;
  14. #endif
  15.  
  16. #define REAL_LRA_SLOT 0
  17. #define KNOWN_RETURN_P_SLOT 1
  18. #define BOGUS_LRA_CONSTANTS 2
  19.  
  20. static inst swap_insts(code_obj, pc_offset, new_inst)
  21.      lispobj code_obj;
  22.      int pc_offset;
  23.      inst new_inst;
  24. {
  25.     struct code *code;
  26.     inst *addr, old_inst;
  27.  
  28.     code = (struct code *)PTR(code_obj);
  29.     addr = (inst *)((char *)code + HeaderValue(code->header)*sizeof(lispobj)
  30.             + pc_offset);
  31.     old_inst = *addr;
  32.     *addr = new_inst;
  33.     os_flush_icache((os_vm_address_t)addr, sizeof(inst));
  34.     return old_inst;
  35. }
  36.  
  37. inst breakpoint_install(code_obj, pc_offset)
  38.      lispobj code_obj;
  39.      int pc_offset;
  40. {
  41.     return swap_insts(code_obj, pc_offset,
  42. #ifdef mips
  43.               (trap_Breakpoint << 16) | 0xd
  44. #endif
  45. #ifdef sparc
  46.               trap_Breakpoint
  47. #endif
  48. #ifdef ibmrt
  49.               0 /* hack */
  50. #endif
  51.     );
  52. }
  53.  
  54. void breakpoint_remove(code_obj, pc_offset, orig_inst)
  55.      lispobj code_obj;
  56.      int pc_offset;
  57.      inst orig_inst;
  58. {
  59.     swap_insts(code_obj, pc_offset, orig_inst);
  60. }
  61.  
  62. static int calc_offset(code, pc)
  63.      struct code *code;
  64.      unsigned long pc;
  65. {
  66.     unsigned long code_start;
  67.     int offset;
  68.  
  69.     code_start = (unsigned long)code
  70.     + HeaderValue(code->header)*sizeof(lispobj);
  71.     if (pc < code_start)
  72.     return 0;
  73.     offset = pc - code_start;
  74.     if (offset >= code->code_size)
  75.     return 0;
  76.     return offset;
  77. }
  78.  
  79. int breakpoint_after_offset(scp)
  80.      struct sigcontext *scp;
  81. {
  82.     struct code *code = (struct code *)PTR(scp->sc_regs[CODE]);
  83.  
  84. #ifdef sparc
  85.     return calc_offset(code, scp->sc_npc);
  86. #endif
  87.  
  88. #ifdef mips
  89.     inst cur_inst = *(inst *)scp->sc_pc;
  90.     int opcode = cur_inst >> 26;
  91.     struct sigcontext tmp;
  92.  
  93.     if (opcode == 1 || ((opcode & 0x3c) == 0x4) || ((cur_inst & 0xf00e0000) == 0x80000000)) {
  94.     tmp = *scp;
  95.     emulate_branch(&tmp, cur_inst);
  96.     return calc_offset(code, tmp.sc_pc);
  97.     }
  98.     else
  99.     return calc_offset(code, scp->sc_pc + 4);
  100. #endif
  101. }
  102.  
  103. static void internal_handle_breakpoint(scp, code)
  104. struct sigcontext *scp;
  105. lispobj code;
  106. {
  107.     struct code *codeptr = (struct code *)PTR(code);
  108.     lispobj *args;
  109.  
  110.     args = current_control_stack_pointer;
  111.     current_control_stack_pointer += 3;
  112.     args[0] = fixnum(calc_offset(codeptr, scp->sc_pc));
  113.     args[1] = code;
  114.     args[2] = alloc_sap(scp);
  115.     call_into_lisp(HANDLE_BREAKPOINT, SymbolFunction(HANDLE_BREAKPOINT),
  116.            args, 3);
  117.     scp->sc_mask = sigblock(0);
  118. }
  119.  
  120. handle_breakpoint(signal, subcode, scp)
  121.      struct sigcontext *scp;
  122. {
  123.     internal_handle_breakpoint(scp, scp->sc_regs[CODE]);
  124. }
  125.  
  126. handle_function_end_breakpoint(signal, subcode, scp)
  127. int signal, subcode;
  128. struct sigcontext *scp;
  129. {
  130.     extern char function_end_breakpoint_guts[], function_end_breakpoint_trap[];
  131.  
  132.     lispobj code = scp->sc_pc - (unsigned long)function_end_breakpoint_trap
  133.     + (unsigned long)function_end_breakpoint_guts -
  134.     ((sizeof(struct code)+((BOGUS_LRA_CONSTANTS-1)*sizeof(lispobj))+7)&~7)
  135.     + type_OtherPointer;
  136.     struct code *codeptr = (struct code *)PTR(code);
  137.     lispobj lra;
  138.  
  139.     internal_handle_breakpoint(scp, code);
  140.  
  141.     lra = codeptr->constants[REAL_LRA_SLOT];
  142.     if (codeptr->constants[KNOWN_RETURN_P_SLOT] == NIL)
  143.     scp->sc_regs[CODE] = lra;
  144.     scp->sc_pc = lra - type_OtherPointer+sizeof(lispobj);
  145. }
  146.  
  147.